using System;
using System.Windows.Forms;

using GSN.Senders;
using GSN.Mail;

using GSN.VersionCheck;

namespace GSN
{
    class GsnApp
    {
        private NotifyIcon notifyIcon = null;
        private Timer timer = new Timer();
        //private IMailManager mManager = null;
        private Notifier notifier = null;

        public void start()
        {
            try
            {
                GSNConfig.verify();
            }
            catch (NoConfigException nce)
            {
                Logger.logException(nce);
                if (MessageBox.Show(
                    "GSN has not been configured. Would you like to do it now?",
                    "Configuration Error", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    try
                    {
                        runConfiguration("", true);
                        //Application.Restart();
                    }
                    catch (Exception ex)
                    {
                        throw new NoConfigException("Failed to run configuration:" + ex.Message);
                    }
                }                
            }           

            // check logging
            try
            {
                if (GSNConfig.getConfigItem(GSNConfig.GSN_CONFIG_LOG).ToLower() == "on")
                    Logger.switchOn();
            }
            catch (ConfigException)
            {
                // do nothing, it's ok.
            }

            Logger.log("GSN Started.");

            notifier = new Notifier();

            // create tray icon

            notifyIcon = new NotifyIcon();
            notifyIcon.Icon = GSN.Properties.Resources.IdleIcon;
            notifyIcon.Visible = true;
            notifyIcon.Text = "GSN";
            notifyIcon.ContextMenu = new ContextMenu(); 
            notifyIcon.ContextMenu.MenuItems.Add("Chec&k Now", new EventHandler(menu_onCheck));

            notifyIcon.ContextMenu.MenuItems.Add("Pause", new EventHandler(menu_onPause)).Name = "Pause";

            MenuItem settingsMenuItem = notifyIcon.ContextMenu.MenuItems.Add("Settings");
            settingsMenuItem.MenuItems.Add("Launch Configuration...", new EventHandler(menu_onConfig));
            settingsMenuItem.MenuItems.Add("Check for New Version", new EventHandler(menu_onCheckVersion));

            if (Logger.isOn())
            {
                settingsMenuItem.MenuItems.Add("Show Log", new EventHandler(menu_onShowLog));
            }

            notifyIcon.ContextMenu.MenuItems.Add("&About...", new EventHandler(menu_onAbout));
            notifyIcon.ContextMenu.MenuItems.Add("-");
            notifyIcon.ContextMenu.MenuItems.Add("E&xit", new EventHandler(menu_onExit));

            // do check when double-clicking
            notifyIcon.DoubleClick += new EventHandler(menu_onCheck);

            // auto version check
            string doAutoVersionCheck = null;
            try
            {
                doAutoVersionCheck = GSNConfig.getConfigItem(GSNConfig.GSN_CONFIG_AUTO_VERSION_CHECK);
            }
            catch (ConfigException)
            {
                // check anyway
                doAutoVersionCheck = "true";
            }
            if (doAutoVersionCheck != null)
            {
                if (bool.Parse(doAutoVersionCheck)) 
                    VersionChecker.check(new VersionCheckDisplayNone()); // check, but don't show any messages
            }

            // start timer
            timer.Tick += new EventHandler(timer_Tick);
            timer.Interval = GSNConfig.getConfigItemInt(GSNConfig.GSN_CONFIG_INTERVAL) * 60 * 1000;
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            Logger.log("Checking...");

            // clear errors if last check is successful
            bool hasErrors = false;

            notifyIcon.Text = "Checking...";
            notifyIcon.Icon = GSN.Properties.Resources.CheckingIcon;          
            
            try
            {                
                notifier.notifyNewMessages();                

            }
            catch (Exception ex)
            {
                Utils.processError(ex);
                hasErrors = true;
            }

            if (!hasErrors)
            {
                // check if in paused or regular mode
                if (notifyIcon.ContextMenu.MenuItems["Pause"].Text == "Pause")
                {
                    // regular
                    notifyIcon.Text = "GSN";
                    notifyIcon.Icon = GSN.Properties.Resources.IdleIcon;
                }
                else
                {
                    notifyIcon.Text = "GSN - Paused";
                    notifyIcon.Icon = GSN.Properties.Resources.PausedIcon;
                }
            }
            else
            {
                notifyIcon.Text = "GSN - Error Occured (Check Log)";
                notifyIcon.Icon = GSN.Properties.Resources.ErrorIcon;
            }

            Logger.log("Checking Done.");
        }

        public void stop()
        {
            // stop timer
            timer.Stop();

            // hide tray icon
            notifyIcon.Visible = false;

            Logger.switchOff();
        }

        private void menu_onPause(object sender, EventArgs e)
        {
            MenuItem item = (MenuItem)sender;
            if (item.Text == "Pause")
            {
                timer.Stop();
                item.Text = "Resume";
                notifyIcon.Text = "GSN - Paused";
                notifyIcon.Icon = GSN.Properties.Resources.PausedIcon;
            }
            else
            {
                timer.Start();
                item.Text = "Pause";
                notifyIcon.Text = "GSN";
                notifyIcon.Icon = GSN.Properties.Resources.IdleIcon;
            }            
            
        }

        private void menu_onExit(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void menu_onShowLog(object sender, EventArgs e)
        {
            if (Logger.isOn())
            {
                try
                {
                    System.Diagnostics.Process.Start(Logger.GSN_LOG_FILENAME);
                }
                catch (Exception ex)
                {
                    Utils.processError(ex, true);
                }
            }
        }

        private void menu_onCheck(object sender, EventArgs e)
        {
            timer.Stop();
            timer_Tick(sender, e);
            timer.Start();
        }

        private void menu_onAbout(object sender, EventArgs e)
        {
            AboutBox box = new AboutBox();
            
            box.ShowDialog();

            box = null;

        }

        private void menu_onConfig(object sender, EventArgs e)
        {
            runConfiguration("", false);
        }

        private void runConfiguration(string parameters, bool waitForExit)
        {
            try
            {
                System.Diagnostics.Process p = new System.Diagnostics.Process();
                p.StartInfo.FileName = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\GSNConf.exe";
                p.StartInfo.Arguments = parameters;
                p.EnableRaisingEvents = true;
                if (!waitForExit)
                    p.Exited += new EventHandler(process_Exited);
                p.Start();

                if (waitForExit)
                {
                    p.WaitForExit();
                    p.Close();
                }
            }
            catch (Exception ex)
            {
                Utils.processError(ex, true);
            }
        }

        private void menu_onCheckVersion(object sender, EventArgs e)
        {
            VersionChecker.check(new VersionCheckDisplayMessageBox());
        }

        void process_Exited(object sender, EventArgs e)
        {            
            ((System.Diagnostics.Process)sender).Close();

            // notifier != null -> configuration during gsn is running
            // notifier == null -> configuration at gsn startup
            if (notifier != null)
            {
                // check if sms/email settings changed
                Notifier newNotifier = new Notifier(notifier);
                if (!notifier.Equals(newNotifier))
                {
                    Logger.log("GSN Configuration changed (SMS/Mail) - Reloading Configuration.");
                    // yes, put new object with new settings
                    notifier = newNotifier;
                }
            }
        }

    }

}